package com.wing.wcabinet.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.cabinet.model.entity.*;
import com.wing.cabinet.model.request.CheckedInventoryInoutDetailForm;
import com.wing.cabinet.model.request.StorageInventoryInoutDetailForm;
import com.wing.cabinet.service.CheckedInventoryInoutService;
import com.wing.cabinet.service.CheckedInventoryProductService;
import com.wing.cabinet.service.UseInventoryUserKnifeService;
import com.wing.common.exception.BusinessException;
import com.wing.order.service.DynamicService;
import com.wing.product.model.entity.ProductDetail;
import com.wing.product.model.response.ProductDetailVO;
import com.wing.product.service.ProductDetailService;
import com.wing.wcabinet.dao.WcabCheckedInventoryInoutDetailDao;
import com.wing.wcabinet.model.entity.WcabCellInventoryInout;
import com.wing.wcabinet.model.entity.WcabCheckedInventoryInout;
import com.wing.wcabinet.model.entity.WcabCheckedInventoryInoutDetail;
import com.wing.wcabinet.model.entity.WcabCheckedInventoryProduct;
import com.wing.wcabinet.model.request.WcabCellInventoryInoutDetailForm;
import com.wing.wcabinet.model.request.WcabCheckedInventoryInoutDetailForm;
import com.wing.wcabinet.model.response.WcabCheckedInventoryInoutDetailVO;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 暂存柜存刀/取刀;存/取维修/回收刀盘验明细-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class WcabCheckedInventoryInoutDetailServiceImpl extends ServiceImpl<WcabCheckedInventoryInoutDetailDao, WcabCheckedInventoryInoutDetail> implements WcabCheckedInventoryInoutDetailService {

    @Autowired
    private DynamicService dynamicService;


    @Autowired
    private WcabCheckedInventoryInoutService inventoryInoutService;

    @Autowired
    private WcabCheckedInventoryProductService inventoryProductService;

    @Autowired
    private UseInventoryUserKnifeService useInventoryUserKnifeService;

    @Autowired
    private ProductDetailService productDetailService;



    @Override
    public int add(WcabCheckedInventoryInoutDetailForm wcabCheckedInventoryInoutDetailForm) {

        //校验

        WcabCheckedInventoryInoutDetail wcabCheckedInventoryInoutDetail =new WcabCheckedInventoryInoutDetail();
        CopyOptions copyOptions = CopyOptions.create()
        .setEditable(WcabCheckedInventoryInoutDetail.class)
        .setIgnoreError(true)
        .setIgnoreNullValue(true);
        BeanUtil.copyProperties(wcabCheckedInventoryInoutDetailForm, wcabCheckedInventoryInoutDetail, copyOptions);

        return baseMapper.insert(wcabCheckedInventoryInoutDetail);
    }

    @Override
    public List<WcabCheckedInventoryInoutDetailVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<WcabCheckedInventoryInoutDetailVO> pageList4app(Page page, Map<String, Object> params) {
        List<WcabCheckedInventoryInoutDetailVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public WcabCheckedInventoryInoutDetailVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }


    @Override
    @Transactional
    public WcabCheckedInventoryInout inventoryIn(List<WcabCellInventoryInoutDetailForm> list, Long storageInoutId, WcabCheckedInventoryInout.BusinessType businessType, WcabCheckedInventoryInout.BusinessTypePre businessTypePre) {
        Long enterpriseId= JwtUtils.getEnterpriseId();
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        Long creator=JwtUtils.getLoginUserId();
        String creatorName=JwtUtils.getLoginUsername();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        WcabCheckedInventoryInout wcabCheckedInventoryInout=new WcabCheckedInventoryInout();
        String code=dynamicService.getDayNextCode("cab_checked_inventory_inout");
        String day=simpleDateFormat.format(new Date());
        wcabCheckedInventoryInout.setCode("IN-"+day+"-"+code);
        wcabCheckedInventoryInout.setDay(Integer.valueOf(day));
        wcabCheckedInventoryInout.setNo(Integer.valueOf(code));
        wcabCheckedInventoryInout.setCreator(JwtUtils.getLoginUserId());
        wcabCheckedInventoryInout.setCreatorName(JwtUtils.getLoginUsername());
        wcabCheckedInventoryInout.setOperationType(WcabCheckedInventoryInout.OperationType.in);
        wcabCheckedInventoryInout.setBusinessType(businessType);
        wcabCheckedInventoryInout.setStorageInoutId(storageInoutId);
//        wcabCheckedInventoryInout.setCompanyId(enterpriseId);
        wcabCheckedInventoryInout.setBusinessTypePre(businessTypePre);
        wcabCheckedInventoryInout.setRemark(businessTypePre.getDesc()+"->"+businessType.getDesc());
        wcabCheckedInventoryInout.setEnterpriseCode(enterpriseCode);
        wcabCheckedInventoryInout.setCreator(creator);
        wcabCheckedInventoryInout.setCreatorName(creatorName);
        inventoryInoutService.save(wcabCheckedInventoryInout);
        List<WcabCheckedInventoryInoutDetailForm> listIn=new ArrayList<>();
        for (WcabCellInventoryInoutDetailForm detailForm:list){
            WcabCheckedInventoryInoutDetailForm cellInventoryInoutDetailForm=new WcabCheckedInventoryInoutDetailForm();
            BeanUtils.copyProperties(detailForm,cellInventoryInoutDetailForm);
            listIn.add(cellInventoryInoutDetailForm);
        }
        saveDetail(listIn,wcabCheckedInventoryInout.getId(), WcabCheckedInventoryInout.OperationType.in.name(),businessType);
        return wcabCheckedInventoryInout;
    }

    @Override
    @Transactional
    public void inventoryOut(List<WcabCheckedInventoryInoutDetailForm> list, WcabCheckedInventoryInout.BusinessType businessType) {
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        WcabCheckedInventoryInout checkedInventoryInout=new WcabCheckedInventoryInout();
        String code=dynamicService.getDayNextCode("cab_checked_inventory_inout");
        String day=simpleDateFormat.format(new Date());
        checkedInventoryInout.setCode("OU-"+day+"-"+code);
        checkedInventoryInout.setDay(Integer.valueOf(day));
        checkedInventoryInout.setNo(Integer.valueOf(code));
        checkedInventoryInout.setCreator(JwtUtils.getLoginUserId());
        checkedInventoryInout.setCreatorName(JwtUtils.getLoginUsername());
        checkedInventoryInout.setOperationType(WcabCheckedInventoryInout.OperationType.out);
        checkedInventoryInout.setBusinessType(businessType);
        checkedInventoryInout.setEnterpriseCode(JwtUtils.getEnterpriseCode());
        inventoryInoutService.save(checkedInventoryInout);

        saveDetail(list,checkedInventoryInout.getId(),UseInventoryInout.Type.out.name(),businessType);
    }



    @Transactional
    void saveDetail(List<WcabCheckedInventoryInoutDetailForm> list, Long inventoryInoutId, String inOutTypeName,WcabCheckedInventoryInout.BusinessType businessType){
        Long enterpriseId=JwtUtils.getEnterpriseId();
        String enterpriseCode=JwtUtils.getEnterpriseCode();
        Long creator=JwtUtils.getLoginUserId();
        String creatorName=JwtUtils.getLoginUsername();
        if (CollectionUtils.isNotEmpty(list)){
            for (WcabCheckedInventoryInoutDetailForm checkedInventoryInoutDetailForm:list){
                WcabCheckedInventoryInoutDetail checkedInventoryInoutDetail=new WcabCheckedInventoryInoutDetail();
                BeanUtils.copyProperties(checkedInventoryInoutDetailForm,checkedInventoryInoutDetail);
                checkedInventoryInoutDetail.setId(null);
//                checkedInventoryInoutDetail.setCompanyId(enterpriseId);
                checkedInventoryInoutDetail.setEnterpriseCode(enterpriseCode);
                checkedInventoryInoutDetail.setCreator(creator);
                checkedInventoryInoutDetail.setCreatorName(creatorName);
                checkedInventoryInoutDetail.setOperationType(WcabCheckedInventoryInoutDetail.OperationType.jsonCreator(inOutTypeName));
                checkedInventoryInoutDetail.setBusinessType(WcabCheckedInventoryInoutDetail.BusinessType.jsonCreator(businessType.name()));
                checkedInventoryInoutDetail.setInoutId(inventoryInoutId);

                List<WcabCheckedInventoryProduct> skuInventoryList=inventoryProductService.list(new QueryWrapper<WcabCheckedInventoryProduct>().eq("sku_code",checkedInventoryInoutDetailForm.getSkuCode()).eq("business_type",businessType.getValue()).eq("enterprise_code",enterpriseCode));

                ProductDetailVO productDetailVO=productDetailService.getProductInfoBySkuCode(checkedInventoryInoutDetailForm.getSkuCode());
                Integer quantity=checkedInventoryInoutDetailForm.getQuantity();

//                if (quantity==null){
//                    quantity=0;
//                }
                BigDecimal weight=checkedInventoryInoutDetailForm.getWeight();
                if (UseInventoryInout.Type.out.name().equals(inOutTypeName)){
                    if (skuInventoryList.size()==0){
                        throw new BusinessException("未找到SKU["+checkedInventoryInoutDetailForm.getSkuCode()+"]的产品");
                    }else{
                        if (quantity<=0){
                            throw new BusinessException("取数量参数异常");
                        }
                        if (quantity>0){
                            quantity=-1*quantity;
                        }

                        Integer currentQuantity=skuInventoryList.get(0).getQuantity();
                        Integer newQuantity=currentQuantity+quantity;
                        if ((productDetailVO!=null&&ProductDetail.InventoryUnitType.quantity.equals(productDetailVO.getInventoryUnitType()))&&newQuantity<0){
                            throw new BusinessException("SKU["+checkedInventoryInoutDetailForm.getSkuCode()+"]的产品库存不足");
                        }

                        if (weight.doubleValue()<=0){
                            throw new BusinessException("取重量参数异常");
                        }
                        if (weight.doubleValue()>0){
                            weight=weight.multiply(BigDecimal.valueOf(-1));
                        }

                        BigDecimal currentWeight=skuInventoryList.get(0).getWeight();
                        BigDecimal newWeight=currentWeight.add(weight);
                        if ((productDetailVO!=null&&ProductDetail.InventoryUnitType.weight.equals(productDetailVO.getInventoryUnitType()))&&newWeight.doubleValue()<0){
                            throw new BusinessException("SKU["+checkedInventoryInoutDetailForm.getSkuCode()+"]的产品库存不足");
                        }



                        WcabCheckedInventoryProduct checkedInventoryProduct=new WcabCheckedInventoryProduct();
                        checkedInventoryProduct.setId(skuInventoryList.get(0).getId());
                        checkedInventoryProduct.setSkuCode(checkedInventoryInoutDetailForm.getSkuCode());
                        checkedInventoryProduct.setQuantity(skuInventoryList.get(0).getQuantity()+quantity);
                        checkedInventoryProduct.setWeight(newWeight);
                        checkedInventoryProduct.setBusinessType(WcabCheckedInventoryProduct.BusinessType.jsonCreator(businessType.name()));
                        if (newQuantity<=0){
                            inventoryProductService.removeById(skuInventoryList.get(0).getId());
                        }else{
                            inventoryProductService.updateById(checkedInventoryProduct);
                        }


                        checkedInventoryInoutDetail.setQuantityCurrent(currentQuantity);
                        checkedInventoryInoutDetail.setQuantityAfter(newQuantity);
                        checkedInventoryInoutDetail.setQuantity(quantity);
                        baseMapper.insert(checkedInventoryInoutDetail);
                    }
                }else if(UseInventoryInout.Type.in.name().equals(inOutTypeName)){
                    if (weight.doubleValue()<=0){
                        throw new BusinessException("存重量参数数异常");
                    }
                    if (quantity<=0){
                        throw new BusinessException("存数量参数数异常");
                    }

                    if (skuInventoryList.size()==0){
                        Integer currentQuantity=0;
                        Integer newQuantity=currentQuantity+quantity;


                        checkedInventoryInoutDetail.setQuantityCurrent(currentQuantity);
                        checkedInventoryInoutDetail.setQuantityAfter(newQuantity);
                        checkedInventoryInoutDetail.setQuantity(quantity);
                        checkedInventoryInoutDetail.setWeightCurrent(BigDecimal.valueOf(0d));
                        checkedInventoryInoutDetail.setWeightAfter(weight);
                        checkedInventoryInoutDetail.setWeight(weight);
                        baseMapper.insert(checkedInventoryInoutDetail);
                    }else{

                        Integer currentQuantity=skuInventoryList.get(0).getQuantity();
                        Integer newQuantity=currentQuantity+quantity;

                        BigDecimal currentWeight=skuInventoryList.get(0).getWeight();
                        BigDecimal newWeight=currentWeight.add(weight);

                        checkedInventoryInoutDetail.setQuantityCurrent(currentQuantity);
                        checkedInventoryInoutDetail.setQuantityAfter(newQuantity);
                        checkedInventoryInoutDetail.setQuantity(quantity);
                        checkedInventoryInoutDetail.setWeightCurrent(currentWeight);
                        checkedInventoryInoutDetail.setWeightAfter(newWeight);
                        checkedInventoryInoutDetail.setWeight(weight);
                        baseMapper.insert(checkedInventoryInoutDetail);
                    }



                    if (skuInventoryList.size()==0){
                        WcabCheckedInventoryProduct checkedInventoryProduct=new WcabCheckedInventoryProduct();
                        checkedInventoryProduct.setSkuCode(checkedInventoryInoutDetailForm.getSkuCode());
                        checkedInventoryProduct.setQuantity(quantity);
                        checkedInventoryProduct.setWeight(weight);
                        checkedInventoryProduct.setBusinessType(WcabCheckedInventoryProduct.BusinessType.jsonCreator(businessType.name()));
//                        checkedInventoryProduct.setCompanyId(enterpriseId);
                        checkedInventoryProduct.setEnterpriseCode(enterpriseCode);
                        inventoryProductService.save(checkedInventoryProduct);
                    }else{
                        WcabCheckedInventoryProduct checkedInventoryProduct=new WcabCheckedInventoryProduct();
                        checkedInventoryProduct.setId(skuInventoryList.get(0).getId());
                        checkedInventoryProduct.setSkuCode(checkedInventoryInoutDetailForm.getSkuCode());
                        checkedInventoryProduct.setQuantity(skuInventoryList.get(0).getQuantity()+quantity);
                        checkedInventoryProduct.setWeight(skuInventoryList.get(0).getWeight().add(weight));
                        checkedInventoryProduct.setBusinessType(WcabCheckedInventoryProduct.BusinessType.jsonCreator(businessType.name()));
                        inventoryProductService.updateById(checkedInventoryProduct);
                    }
                }else{
                    throw new BusinessException("出入库类型参数异常");
                }

            }
        }else{
            throw new BusinessException("未提交存放数据");
        }
    }
}
